/**
 * 上海中赢金融信息服务有限公司
 * Copyright (c) 2016-2026 HMC,Inc.All Rights Reserved.
 */
package com.sys.midware.redis.core.handler;

import org.apache.log4j.Logger;

import com.sys.midware.redis.core.RedisFactory;
import com.sys.midware.redis.core.operation.AbstractOperations;
import com.sys.midware.redis.core.operation.HashOperations;
import com.sys.midware.redis.core.operation.KeyOperations;
import com.sys.midware.redis.core.operation.ListOperations;
import com.sys.midware.redis.core.operation.SetOperations;
import com.sys.midware.redis.core.operation.StringsOperations;
import com.sys.midware.redis.core.operation.ZSetOperations;
import com.sys.midware.redis.core.operation.impl.ClusterHashOperationsImpl;
import com.sys.midware.redis.core.operation.impl.ClusterKeyOperationsImpl;
import com.sys.midware.redis.core.operation.impl.ClusterListOperationsImpl;
import com.sys.midware.redis.core.operation.impl.ClusterSetOpertionsImpl;
import com.sys.midware.redis.core.operation.impl.ClusterStringsOperationsImpl;
import com.sys.midware.redis.core.operation.impl.ClusterZSetOperationsImpl;
import com.sys.midware.redis.exceptions.BRedisException;

import redis.clients.jedis.JedisCluster;

/**
 * Redis 工具类
 * 
 */
public class RedisHandlerCluster extends AbstractOperations  implements RedisHandler {

    protected static Logger logger = Logger.getLogger(RedisHandlerCluster.class);

    /** 默认缓存时间 */
    private static final int DEFAULT_CACHE_SECONDS = 60 * 60 * 24;// 单位秒 设置成24小时


    private RedisHandlerCluster() {
    };

    private static RedisHandlerCluster instance;

    /**
     * 获取单例工厂
     * 
     * @return
     * @throws Exception
     */
    public static RedisHandlerCluster getInstance() {
        if (instance != null)
            return instance;

        synchronized (RedisHandlerCluster.class) {
            if (instance == null) {
                instance = new RedisHandlerCluster();
            }
            return instance;
        }
    }

    /**
     * 保存一个对象到redis中并指定默认时间 <br/>
     * save <br/>
     * 
     * @param key
     * @param value
     * @param expireTimeSeconds
     * @return boolean <br/>
     */
    public <K, V> boolean save(K key, V value) {
        return save(key, value, DEFAULT_CACHE_SECONDS);
    }

    
    /**
     * 保存一个对象到redis中并指定过期时间 <br/>
     * save <br/>
     * 
     * @param key
     * @param value
     * @param expireTimeSeconds
     * @return boolean <br/>
     */
    public <K, V> boolean save(K key, V value, int expireTimeSeconds) {
         JedisCluster jedis = getClient4Cluster();
        try {
                jedis.set(rawKey(key),rawValue(value));
                jedis.expire(rawKey(key), expireTimeSeconds);
            return true;
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException(e);
        } finally {
//            RedisFactory.close(jedis);
        }
    }


    /**
     * 根据缓存键清除Redis缓存中的值.<br/>
     * 
     * @param keys
     * @return
     * @throws Exception
     */
    public boolean delete(Object... keys) {
        JedisCluster jedis = getClient4Cluster();
        try {
                jedis.del(rawKeys(keys));
            return true;
        } catch (Exception e) {
            throw new BRedisException(e);
        } finally {
//            RedisFactory.close(jedis);
        }
    }


    /**
     * 设置某个key的过期时间 <br/>
     * expire <br/>
     * 
     * @param key
     * @param seconds
     * @return long <br/>
     */
    public <K> long expire(K key, int seconds) {
        JedisCluster jedis = getClient4Cluster();
        try {
            return jedis.expire(rawKey(key), seconds);
        } catch (Exception e) {
            throw new BRedisException(e);
        } finally {
//            RedisFactory.close(jedis);
        }
    }
    /**
     * 查看键的剩余生存时间<br/>
     * ttl <br/>
     * 
     * @param key
     * @param seconds
     * @return long <br/>
     */
    public <K> long ttl(K key) {
        JedisCluster jedis = getClient4Cluster();
        try {
            return jedis.ttl(rawKey(key));
        } catch (Exception e) {
            throw new BRedisException(e);
        } finally {
        }
    }
    /**
     * 获取对象 get <br/>
     * @param key
     * @return V <br/>
     */
    public <K, V> V get(K key) {
        JedisCluster jedis = getClient4Cluster();
        try {
               byte[] reByte = jedis.get(rawKey(key));
            return deserializeValue(reByte);
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException("redis 获取数据出错!", e);
        } finally {
//            RedisFactory.close(jedis);
        }
    }
    @Override
    public ListOperations opsForList() {
        return ClusterListOperationsImpl.getInstance();
    }

    @Override
    public HashOperations opsForHash() {
        return ClusterHashOperationsImpl.getInstance();
    }

    @Override
    public SetOperations opsForSet() {
        return ClusterSetOpertionsImpl.getInstance();
    }

    @Override
    public ZSetOperations opsForZSet() {
        return ClusterZSetOperationsImpl.getInstance();
    }

    @Override
    public StringsOperations opsForString() {
        return ClusterStringsOperationsImpl.getInstance();
    }

    @Override
    public KeyOperations opsForKey() {
        return ClusterKeyOperationsImpl.getInstance();
    }

    @Override
    public void clear() {
        JedisCluster jedis = getClient4Cluster();
        try {
            jedis.flushDB();
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException("redis clear error!", e);

        } finally {
            RedisFactory.close(jedis);
        }
        
    }

    @Override
    public Long getSize() {
        JedisCluster jedis = getClient4Cluster();
        try {
           return jedis.dbSize();
        } catch (Exception e) {
            logger.error(e);
            throw new BRedisException("redis clear error!", e);

        } finally {
            RedisFactory.close(jedis);
        }
        
    }

}
